home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 23
/
AACD 23.iso
/
AACD
/
Sound
/
RAPlay
/
src
/
RAPlay.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-06-15
|
9KB
|
383 lines
#define __USE_SYSBASE
#include <stdio.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <proto/asyncio.h>
#include <proto/ahi.h>
#ifdef __PPC__
#include <powerup/gcclib/powerup_protos.h>
#undef SetSignal
#define SetSignal PPCSetSignal
#endif
#include "common.h"
static const char version[]="$VER: RAPlay 2.0 (15.06.01) The Amiga RealAudio 14.4/28.8 player/decoder, thanks to all!";
ULONG __nocommandline;
ULONG __stack = 16384;
#if 0
BOOL FastTable = 0;
#endif
struct Library *AsyncIOBase = NULL;
AsyncFile *InputFile = NULL;
AsyncFile *OutputFile = NULL;
Real_144 *Real144 = NULL;
Real_288 *Real288 = NULL;
struct MsgPort *AHImp = NULL;
struct AHIRequest *AHIio = NULL;
struct AHIRequest *AHIio2 = NULL;
BYTE AHIDevice = -1;
struct RDArgs *rdargs = NULL;
#if 0
STRPTR Template = "INPUT,OUTPUT,U=UNIT/K/N,FAST/S";
enum { TEM_INPUT, TEM_OUTPUT, TEM_UNIT, TEM_FAST, TEM_NUMARGS };
#else
STRPTR Template = "INPUT,OUTPUT,U=UNIT/K/N";
enum { TEM_INPUT, TEM_OUTPUT, TEM_UNIT, TEM_NUMARGS };
#endif
signed short *outbuf=NULL,*dubbuf=NULL;
#ifndef __GNUC__
static int break_cleanup(void)
{
/* Just a dummy so atexit() will work */
return 1;
}
#endif
static void exit_cleanup(void)
{
if(outbuf);
{
FreeMem(outbuf,AUDIOBUFFER*sizeof(short));
outbuf = NULL;
}
if(dubbuf);
{
FreeMem(dubbuf,AUDIOBUFFER*sizeof(short));
dubbuf = NULL;
}
if(Real144);
{
free_144(Real144);
Real144 = NULL;
}
if(Real288);
{
free_288(Real288);
Real288 = NULL;
}
if(InputFile);
{
CloseAsync(InputFile);
InputFile = NULL;
}
if(OutputFile);
{
CloseAsync(OutputFile);
OutputFile = NULL;
}
if(AsyncIOBase)
{
CloseLibrary(AsyncIOBase);
AsyncIOBase = NULL;
}
if(!AHIDevice)
{
CloseDevice((struct IORequest *)AHIio);
AHIDevice = -1;
}
if(AHIio)
{
DeleteIORequest((struct IORequest *)AHIio);
AHIio = NULL;
}
if(AHIio2)
{
DeleteIORequest((struct IORequest *)AHIio2);
AHIio2 = NULL;
}
if(AHImp)
{
DeleteMsgPort(AHImp);
AHImp = NULL;
}
if(rdargs)
{
FreeArgs(rdargs);
rdargs = NULL;
}
}
void Fail(STRPTR reason)
{
BPTR StdErr;
if ((StdErr = Open("CONSOLE:", MODE_NEWFILE)))
{
FPrintf(StdErr, "%s\n", reason);
Close(StdErr);
}
exit(20);
}
int main(void)
{
ULONG unit=0;
BOOL terminated=FALSE;
ULONG signals,AHIcount=0;
struct AHIRequest *link = NULL;
LONG ArgArray[TEM_NUMARGS];
BPTR StdIn, StdOut;
unsigned int s,x,bufsiz,size,blocksize,chunksize;
unsigned char in[DATACHUNK2];
unsigned char deint[DATACHUNK2];
void *tmp;
for(x=0;x<TEM_NUMARGS;ArgArray[x++]=NULL);
if(!(rdargs=ReadArgs(Template,ArgArray,NULL))) Fail("Unable to read arguments.");
StdIn = Input();
StdOut = Output();
if(!ArgArray[TEM_INPUT])
{
if(IsInteractive(StdIn)) Fail("No input specified.");
else if(IsInteractive(StdOut)) Fail("Please redirect output or use proper arguments instead.");
}
if(ArgArray[TEM_UNIT]) unit=*((ULONG *)ArgArray[TEM_UNIT]);
if(unit>3) Fail("Illegal unit number!");
#if 0
if(ArgArray[TEM_FAST]) FastTable=1;
#endif
if(ArgArray[TEM_INPUT])
{
if(!(AsyncIOBase=OpenLibrary("asyncio.library", 39))) Fail("Unable to open asyncio.library.");
#ifndef __GNUC__
onbreak(break_cleanup);
#endif
atexit(exit_cleanup);
if(!(InputFile=OpenAsync((STRPTR)ArgArray[TEM_INPUT], MODE_READ, 16384))) Fail("Unable to open input file.");
if(ArgArray[TEM_OUTPUT])
{
if(!(OutputFile=OpenAsync((STRPTR)ArgArray[TEM_OUTPUT], MODE_WRITE, 32768))) Fail("Unable to open output file.");
}
else
{
if(AHImp=CreateMsgPort())
if(AHIio=(struct AHIRequest *)CreateIORequest(AHImp,sizeof(struct AHIRequest)))
{
AHIio->ahir_Version = 4;
AHIDevice=OpenDevice(AHINAME,unit,(struct IORequest *)AHIio,NULL);
}
if(AHIDevice) Fail("Unable to open ahi.device v4");
if(!(AHIio2=AllocMem(sizeof(struct AHIRequest), MEMF_ANY))) Fail("Unable to allocate needed memory.");
CopyMem(AHIio, AHIio2, sizeof(struct AHIRequest));
}
if(ReadAsync(InputFile,in,6) <= 0) Fail("Unexpected EOF or error while reading.");
}
else Read(StdIn,in,6);
if(in[0]=='.'&&in[1]=='R'&&in[2]=='M'&&in[3]=='F') Fail("RealMedia streams are not supported!!!");
if(in[0]=='.'&&in[1]=='r'&&in[2]=='a'&&in[3]==0xfd)
{
if(in[5]==4)
{
if(ArgArray[TEM_INPUT])
{
if(ReadAsync(InputFile,in,55) <= 0) Fail("Unexpected EOF or error while reading.");
}
else Read(StdIn,in,55);
if(in[54]=='0') Fail("Int0 28.8 streams are not supported!!!");
if(in[54]=='r') Fail("RealMedia streams are not supported!!!");
x=(in[12]<<24|in[13]<<16|in[14]<<8|in[15])-45;
if(ArgArray[TEM_INPUT])
{
if(ReadAsync(InputFile,in,x) <= 0) Fail("Unexpected EOF or error while reading.");
}
else Read(StdIn,in,x);
blocksize=DATABLOCK2;
chunksize=DATACHUNK2;
Real288 = init_288();
}
else if(in[5]==3)
{
if(ArgArray[TEM_INPUT])
{
if(ReadAsync(InputFile,in,2) <= 0) Fail("Unexpected EOF or error while reading.");
}
else Read(StdIn,in,2);
while(in[0])
{
if(ArgArray[TEM_INPUT])
{
if(ReadAsync(InputFile,in,256) <= 0) Fail("Unexpected EOF or error while reading.");
}
else Read(StdIn,in,256);
}
if(ArgArray[TEM_INPUT])
{
if(ReadAsync(InputFile,in,in[1]) <= 0) Fail("Unexpected EOF or error while reading.");
}
else Read(StdIn,in,in[1]);
blocksize=DATABLOCK1;
chunksize=DATACHUNK1;
Real144 = init_144();
}
else Fail("Not a 14.4 or 28.8 stream!!!");
}
else Fail("Unrecognized format!!!");
if(AHImp) if(!(dubbuf = (signed short *)AllocMem(AUDIOBUFFER*sizeof(short), MEMF_ANY | MEMF_CLEAR))) Fail("Unable to allocate needed memory.");
if(!(outbuf=(signed short *)AllocMem(AUDIOBUFFER*sizeof(short), MEMF_ANY | MEMF_CLEAR))) Fail("Unable to allocate needed memory.");
if(ArgArray[TEM_INPUT])
{
while((s=size=ReadAsync(InputFile,in,chunksize))>0)
{
bufsiz=0;
if (!(size/=blocksize)) break;
if(blocksize==DATABLOCK1) {
for(x=0;x<size;x++)
{
decode_144(Real144,in+blocksize*x,&outbuf[bufsiz]);
bufsiz+=AUDIOBLOCK;
}
} else {
deinterleave(in,deint,s);
for(x=0;x<size;x++)
{
decode_288(Real288,deint+blocksize*x,&outbuf[bufsiz]);
bufsiz+=AUDIOBLOCK;
}
}
if(AHImp)
{
AHIio->ahir_Std.io_Message.mn_Node.ln_Pri = 0;
AHIio->ahir_Std.io_Command = CMD_WRITE;
AHIio->ahir_Std.io_Data = outbuf;
AHIio->ahir_Std.io_Length = bufsiz*sizeof(short);
AHIio->ahir_Std.io_Offset = 0;
AHIio->ahir_Frequency = 8000;
AHIio->ahir_Type = AHIST_M16S;
AHIio->ahir_Volume = 0x10000;
AHIio->ahir_Position = 0x8000;
AHIio->ahir_Link = link;
SendIO((struct IORequest *) AHIio);
AHIcount++;
if(link)
{
signals=Wait(SIGBREAKF_CTRL_C | (1L << AHImp->mp_SigBit));
#ifdef __PPC__
if(SetSignal(0,0) & SIGBREAKF_CTRL_C)
#else
if(signals & SIGBREAKF_CTRL_C)
#endif
{
terminated=TRUE;
break;
}
if(WaitIO((struct IORequest *) link)) Fail("I/O request failed.");
}
link = AHIio;
tmp = outbuf;
outbuf = dubbuf;
dubbuf = tmp;
tmp = AHIio;
AHIio = AHIio2;
AHIio2 = tmp;
}
else
{
WriteAsync(OutputFile,outbuf,bufsiz*sizeof(short));
if(SetSignal(0,0) & SIGBREAKF_CTRL_C) break;
}
}
}
else
{
while((s=size=Read(StdIn,in,chunksize))>0)
{
bufsiz=0;
if (!(size/=blocksize)) break;
if(blocksize==DATABLOCK1) {
for(x=0;x<size;x++)
{
decode_144(Real144,in+blocksize*x,&outbuf[bufsiz]);
bufsiz+=AUDIOBLOCK;
}
} else {
deinterleave(in,deint,s);
for(x=0;x<size;x++)
{
decode_288(Real288,deint+blocksize*x,&outbuf[bufsiz]);
bufsiz+=AUDIOBLOCK;
}
}
Write(StdOut,outbuf,bufsiz*sizeof(short));
if(SetSignal(0,0) & SIGBREAKF_CTRL_C) break;
}
}
if(AHIcount)
{
if(terminated)
{
AbortIO((struct IORequest *) AHIio);
WaitIO((struct IORequest *) AHIio);
if(AHIcount>1)
{
AbortIO((struct IORequest *) AHIio2);
WaitIO((struct IORequest *) AHIio2);
}
}
else WaitIO((struct IORequest *) AHIio2);
}
return 0;
}